#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <signal.h>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void handler(int signo)
{
    cout << "我是一个而进程，刚刚获取了一个信息：" << signo << endl;
}

static void showPending(sigset_t *pendings)
{
    for (int sig = 1; sig <= 31; sig++)
    {
        if (sigismember(pendings, sig))
            cout << "1";
        else
            cout << "0";
    }
    cout << endl;
}

int main()
{
    cout << "pid:" << getpid() << endl;

    // 3.屏蔽2号信号
    sigset_t bsig, obsig;
    sigemptyset(&bsig);
    sigemptyset(&obsig);
    // sigfillset();
    for (int sig = 1; sig <= 31; sig++)
    {
        // 3.1 添加2号信号到信号屏蔽字中
        sigaddset(&bsig, 2);
        // 2.signal
        signal(sig, handler);
    }
    // 3.2 设置用户级的信号屏蔽字到内核中，让当前进行屏蔽2号信号
    sigprocmask(SIG_SETMASK, &bsig, &obsig);

    // 1.不断获取当前进程的pending信号集
    sigset_t pendings;
    int cnt = 0;
    while (true)
    {
        // 1.1 清空信号集
        sigemptyset(&pendings);
        // 1.2 获取当前进行的pending信号集
        if (sigpending(&pendings) == 0)
        {
            // 1.3 打印一下当前进程的pending信号集
            showPending(&pendings);
        }
        sleep(1);
        cnt++;
        if (cnt == 20)
        {
            cout << "解除对所有信号的block..." << endl;
            sigset_t sigs;
            sigemptyset(&sigs);
            sigaddset(&sigs, 2);
            sigprocmask(SIG_SETMASK, &obsig, nullptr);
        }
    }
    return 0;
}

// int cnt = 0;

// void handler(int signo)
// {
//     cout << "我是一个而进程，刚刚获取了一个信息：" << signo << endl;
// }

// // core dump
// int main()
// {
//     pid_t id = fork();
//     if (id == 0)
//     {
//         // int *p = nullptr;
//         // *p = 1234;

//         int a=10;
//         a/=0;
//         exit(1);
//     }

//     int status = 0;
//     waitpid(id, &status, 0);
//     printf("exitcode:%d, signo:%d, core dump flag:%d\n", (status >> 8) & 0xff, status & 0x7f, (status >> 7) & 0x1);
//     return 0;
// }

// int main()
// {
//     // 统计一下我们的进程1s中会将cnt++多少次
//     alarm(1);

//     while (1)
//     {
//         cout << "hello:" << cnt++ << endl;
//     }

//     // signal(2,handler);
//     // signal(SIGABRT,handler);

//     // while(1)
//     // {
//     //     sleep(1);
//     //     //raise(2);
//     //     abort();
//     // }
//     return 0;
// }

// int main()
// {
//     // 这不是调用handler方法，这是设置了一个回调，当SIGINT信息产生的时候，该方法才会被调用
//     // 如果不产生SIGINT，该方法不会被调用
//     // ctrl+c：本质就是给前台进程产生了2号信息，发送给目标进程，目标进程默认对2号信息的处理，就是终止自己
//     // 这里对2号信号，设置了用户自定义处理方法
//     signal(SIGINT, handler);
//     signal(3, handler);
//     signal(9, handler);

//     sleep(3);
//     cout << "进程已经设置完了" << endl;
//     sleep(3);

//     while (true)
//     {
//         cout << "我是一个正在运行中的进程：" << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }
